#include "csb.h"
#include "csobj.h"

/*********************| 内部数据结构 |*********************/

/* 层数据 */
typedef struct {
	uint32_t	nEmitter;	// 发射器数目
	uint32_t	nLaser;		// 激光数目
//	uint32_t*	emitterDataLen;	// 发射器的数据长度数组
//	uint32_t*	LaserDataLen;	// 激光的数据长度数组
//	csobjdata_t*	pCsobj;		// 元素数组指针 (最终目的就是收集这个)
}layerhead_t;

/* csb数据结构 */
typedef struct {
	uint32_t	ver;	// 版本号
	uint32_t	nLayer;	// 总层数
	uint32_t	totalFrame;
//	layer_t*	pLy;	// 层数组指针
}csbhead_t;

#define VERSION	0x01
/*********************| 外部接口 |*********************/

list_t* load_csbdata(unsigned char* pdata)
{
	csberrno = CSBERR_NOERR;
	CSB_NO_ERR_RET(pdata, CSBERR_PARAM, NULL);
	// check file head
	csbhead_t* pcsb = (csbhead_t*)pdata;
	CSB_YES_ERR_RET(pcsb->ver != VERSION, CSBERR_FILETYPE, NULL);
	CSB_LOG("read csb data successfully.\n");
	CSB_LOG("layer number = %u\n", pcsb->nLayer);
	size_t offset = sizeof(csbhead_t);
	uint32_t i = 0;
	uint32_t j = 0;
	layerhead_t* pLayer = NULL;
	uint32_t* emitterDataLen = NULL;
	uint32_t* laserDataLen = NULL;
	csobjdata_t* pcsobj = NULL;
	list_t* objlist = list_new();
	for (i = 0; i < pcsb->nLayer; ++i) {
		pLayer = (layerhead_t*)(pdata + offset);
		offset += sizeof(layerhead_t);
		emitterDataLen = (uint32_t*)(pdata + offset);
		offset += sizeof(uint32_t) * pLayer->nEmitter;
		laserDataLen = (uint32_t*)(pdata + offset);
		offset += sizeof(uint32_t) * pLayer->nLaser;
		CSB_LOG("in layer %u, emitter num = %u, laser num = %u\n", i,
		       pLayer->nEmitter, pLayer->nLaser);
		for (j = 0; j < pLayer->nEmitter; ++j) {
			pcsobj = csobjdata_read(EMITTER, pdata + offset, pcsb->totalFrame);
			if (pcsobj) {
				list_insert(objlist, (void*)pcsobj, 0, 1);
			}
			CSB_LOG("\temitter(%u) data len = %u\n", j, *emitterDataLen);
			offset += *emitterDataLen;
			++emitterDataLen;
		}
		CSB_LOG("\t----------------------------------\n");

		for (j = 0; j < pLayer->nLaser; ++j) {
			pcsobj = csobjdata_read(LASER, pdata + offset, pcsb->totalFrame);
			if (pcsobj) {
				list_insert(objlist, (void*)pcsobj, 0, 1);
			}
			offset += *laserDataLen;
			++laserDataLen;
		}
	}
	return objlist;
}

list_t* load_csb(const char* csbfpath)
{
	// 打开文件判断大小
	csberrno = CSBERR_NOERR;
	CSB_NO_ERR_RET(strlen(csbfpath), CSBERR_PARAM, NULL);
	FILE* fp = fopen(csbfpath, "rb");
	unsigned char pdata[FILE_BUF_SIZE] = {0};
	long pos = 0;
	CSB_NO_ERR_RET(fp, CSBERR_OPENFILE, NULL);
	TEST_ERR_GOTO(fseek(fp, 0, SEEK_END) < 0, CSBERR_SYSERR, do_err);
	pos = ftell(fp);
	TEST_ERR_GOTO(pos < 0, CSBERR_SYSERR, do_err);
	if (0 == pos) {
		goto do_err;
	}
	TEST_ERR_GOTO(pos > FILE_BUF_SIZE, CSBERR_FILETOOLARGE, do_err);
	fseek(fp, 0, SEEK_SET);
	TEST_ERR_GOTO(fread(pdata, (size_t)pos, 1, fp) < 1, CSBERR_SYSERR, do_err);
	fclose(fp);
	// 调用load_csbdata解析数据
	return load_csbdata(pdata);
do_err:
	fclose(fp);
	return NULL;
}

